import java.util.List;
import java.util.Map;

public class GeneratePredictMap {
    //保存需要的相关信息
    private List<Formula> formulas;
    private List<String> terminals;
    private List<String> nonTerminals;
    private Map<String, List<String>> firsts;
    private Map<String, List<String>> follows;
    private Map<String, Formula> predictions;

    public GeneratePredictMap(List<Formula> formulas,
                              List<String> terminals,
                              List<String> nonTerminals,
                              Map<String, List<String>> firsts,
                              Map<String, List<String>> follows,
                              Map<String, Formula> predictions) {
        this.formulas = formulas;
        this.terminals = terminals;
        this.nonTerminals = nonTerminals;
        this.firsts = firsts;
        this.follows = follows;
        this.predictions = predictions;
    }

    public void setPredictions() {
        for (Formula formula : formulas) {
            // First(formula.right[0])
            try {
                if (formula.getRight()[0].equals("$")) { // 类似于 value' -> $ 这种文法
                    // First集合中First($)是不存在的
                    // 遇到这种文法直接跳过
                    continue;
                }
                for (String terminalInFirsts : firsts.get(formula.getRight()[0])) {
                    // 空
                    if (terminalInFirsts.equals("$")) {
                        // Follow(formula.left)
                        for (String terminalInFollows : follows.get(formula.getLeft())) {
                            predictions.put(getMapKey(terminalInFollows, formula.getLeft()),
                                    new Formula(formula.getLeft(), new String[]{"$"}));
                        }
                    }
                    // 不空
                    // [Terminal, notTerminal] : formula
                    predictions.put(getMapKey(terminalInFirsts, formula.getLeft()), formula);
                }
            } catch (Exception e) {
                System.out.println("first结合中没有 key: " + formula.getRight()[0]);
                e.printStackTrace();
            }
        }

        // (3)
        // E -> $
        for (Formula formula : formulas) {
            if (formula.getRight()[0].equals("$")) {    // E -> $
                for (String followElement : follows.get(formula.getLeft())) { // Follow(E)
                    // [FollowElement(E), E] : E - > $
                    predictions.put(getMapKey(followElement, formula.getLeft()), formula);
                }
            }
        }
    }

    // 以固定的格式产生分析表的 Key
    static String getMapKey(String terminal, String nonTerminal) {
        // i 为终结符，横坐标
        // j 为非终结符，纵坐标
        return  "{横坐标: " + terminal + "  " + "纵坐标: " + nonTerminal + "}";
    }

}
